package com.pignest.hotel.dao.hibernate;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Expression;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.pignest.framework.dao.BaseHibernateDao;
import com.pignest.hotel.beans.Room;
import com.pignest.hotel.beans.RoomType;
import com.pignest.hotel.dao.RoomDao;
import com.pignest.hotel.definition.RoomLiveStatus;
import com.pignest.hotel.definition.RoomStatus;

@SuppressWarnings("unchecked")
public class RoomHibernateDao extends BaseHibernateDao implements RoomDao {
	
	@Override
	public String defaultOrderBy() {
		return "floor asc, name asc";
	}

	public List<Room> listRooms(RoomType... roomTypes) {
		if (roomTypes == null || roomTypes.length == 0)
			return listAll(Room.class);
		if (roomTypes.length == 1) {
			return findByHQLUseList("from Room where type=:type", new String[] {"type"}, new Object[] {roomTypes[0]}, 0, 0);
		}
		Criteria criteria = getSession().createCriteria(Room.class);
		Criterion expr = Expression.eq("type", roomTypes[0]);
		for (int i = 1; i<roomTypes.length ; i++) {
			expr = Expression.or(expr, Expression.eq("type", roomTypes[i]));
		}
		criteria.add(expr);
		return criteria.list();
	}
	
	public List<Room> listRooms(RoomLiveStatus liveStatus, RoomType... roomTypes) {
		if ((roomTypes == null || roomTypes.length == 0) && liveStatus == null)
			return listAll(Room.class);
		StringBuilder sb = new StringBuilder();
		List<String> params = new ArrayList<String>();
		List<Object> values = new ArrayList<Object>();
		sb.append("from Room where ");
		if (liveStatus != null) {
			sb.append("liveStatus=:status and ");
			params.add("status");
			values.add(liveStatus.name());
		}
		if (roomTypes == null || roomTypes.length == 0) {
			return findByHQLUseList(sb.toString(), params.toArray(new String[params.size()]), values.toArray(new Object[params.size()]), 0, 0);
		}
		if (roomTypes != null && roomTypes.length == 1) {
			sb.append("type=:type");
			params.add("type");
			values.add(roomTypes[0]);
			return findByHQLUseList(sb.toString(), params.toArray(new String[params.size()]), values.toArray(new Object[params.size()]), 0, 0);
		}
		Criteria criteria = getSession().createCriteria(Room.class);
		Criterion expr = Expression.eq("type", roomTypes[0]);
		for (int i = 1; i<roomTypes.length ; i++) {
			expr = Expression.or(expr, Expression.eq("type", roomTypes[i]));
		}
		criteria.add(expr);
		if (liveStatus != null) {
			expr = Expression.eq("liveStatus", liveStatus.name());
			criteria.add(expr);
		}
		return criteria.list();
	}
	public List<Room> listRooms(String... roomTypeIds) {
		if (roomTypeIds == null || roomTypeIds.length == 0)
			return listAll(Room.class);
		if (roomTypeIds.length == 1) {
			return findByHQLUseList("from Room where type.id=:typeId", new String[] {"typeId"}, new Object[] {roomTypeIds[0]}, 0, 0);
		}
		Criteria criteria = getSession().createCriteria(Room.class);
		Criterion expr = Expression.eq("type.id", roomTypeIds[0]);
		for (int i = 1; i<roomTypeIds.length ; i++) {
			expr = Expression.or(expr, Expression.eq("type.id", roomTypeIds[i]));
		}
		criteria.add(expr);
		return criteria.list();
	}

	public boolean hasRooms(String... roomTypes) {
		if (roomTypes == null)
			return false;
		for (int i = 0; i < roomTypes.length; i++) {
			List<Room> rooms = findByHQLUseList("from Room where type.id=:roomTypeId", new String[] {"roomTypeId"}, new Object[] {roomTypes[i]}, 0, 1);
			if (rooms != null && rooms.size() > 0)
				return true;
		}
		return false;
	}

	@Override
	public String getRoomTypeByName(String name) {
		String hql =" select e from Room m ,RoomType e where e.id = m.type.id and m.name=?";
		List list = this.getHibernateTemplate().find(hql, new String[]{name});
		if(list.size()==0) return "";
		RoomType roomtype = (RoomType)list.get(0);
		if(roomtype==null) 
			return "";
		else 
			return roomtype.getName();
	}
	
	public Room getRoomByName(String name) {
		String hql = "from Room where name=?";
		List<Room> rooms = getHibernateTemplate().find(hql, name);
		return rooms == null || rooms.isEmpty() ? null : rooms.get(0);
	}
	/** 通过房间名获取锁号*/
	public String getRoomLockByName(String roomName){
		String hql =" from Room where name=?";
		List<Room> rooms = getHibernateTemplate().find(hql, roomName);
		return rooms == null || rooms.isEmpty() ? null : rooms.get(0).getLockNumber();
	}
	public List<Room> listSelfHelpRooms(final String roomTypeId) {
		return (List<Room>)getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query q;
				String hql;
				if (StringUtils.isEmpty(roomTypeId)) {
					hql = "from Room where selfHelp=true and " + RoomStatus.SELF_HELP.toHql(null);
					q = session.createQuery(hql);
//					q.setBoolean("selfHelp", true);
				} else {
					hql = "from Room where type.id=:typeId and selfHelp=:selfHelp and " + RoomStatus.SELF_HELP.toHql(null);
					q = session.createQuery(hql);
					q.setBoolean("selfHelp", true);
					q.setString("typeId", roomTypeId);
				}
				return q.list();
			}
		});
	}

	public List<Room> listBookingRooms() {
		return (List<Room>)getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				String hql = "from Room where " + RoomStatus.BOOKING.toHql(null);
				Query q = session.createQuery(hql);
				return q.list();
			}
		});
	}
}
